package Controller

import (
	"back_go/DAO/gorm"
	"back_go/DAO/gorm/GormModel"
	"back_go/Response"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm/clause"
	"log"
	"math"
	"net/http"
	"strconv"
	"time"
)

// GetPickAddrPage 自取地址分页
/*
 参数：
  current: 当前页码，默认为1
  size: 每页数量，默认为10
  addrName: 地址名称，模糊查询
返回：
  code: 00000 成功，其他失败
  data: 分页数据
*/
func GetPickAddrPage(c *gin.Context) {
	// 从uri上面获取size, current, addrName
	currentStr := c.Query("current")
	sizeStr := c.Query("size")
	addrName := c.Query("addrName")

	var db = gorm.Db

	var page, size int
	var err error
	if page, err = strconv.Atoi(currentStr); err != nil || page < 1 {
		page = 1
	}
	if size, err = strconv.Atoi(sizeStr); err != nil || size < 1 {
		size = 10
	}
	offset := (page - 1) * size

	// 构建查询条件
	query := db.Table("tz_pick_addr")
	if addrName != "" {
		query = query.Where("addr_name LIKE ?", "%"+addrName+"%")
	}

	// 执行查询并获取结果
	var pickAddrs []GormModel.TzPickAddr
	err = query.Order(clause.OrderByColumn{Column: clause.Column{Name: "addr_id"}, Desc: true}).Offset(offset).Limit(size).Find(&pickAddrs).Error
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:      "A00005",
			Data:      nil,
			Msg:       "服务器出了问题",
			Version:   "1.0",
			Timestamp: time.Now().Unix(),
			Sign:      "",
			Fail:      true,
			Success:   false,
		})
		return
	}

	// 计算总数
	var count int64
	err = query.Count(&count).Error
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 构造响应
	c.JSON(http.StatusOK, Response.ResponseBody{
		Code: "00000",
		Data: PageParam1[GormModel.TzPickAddr]{
			Current: page,
			Total:   count,
			Size:    size,
			Records: pickAddrs,
			Pages:   int(math.Ceil(float64(count) / float64(size))),
		},
		Msg:       nil,
		Success:   true,
		Fail:      false,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
	})
}

// GetPickAddrById 通过id去获取
/*
  参数：
   id: 自取地址id
 返回：
  code: 00000 成功，其他失败
  data: 查询到的自取地址信息
*/
func GetPickAddrById(c *gin.Context) {
	var db = gorm.Db
	PickAddId := c.Param("id")
	PickAddID, err := strconv.Atoi(PickAddId)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "A00001",
			"msg":     "Invalid transport ID",
			"data":    nil,
			"success": false,
		})
		return
	}
	var pickAddr GormModel.TzPickAddr
	if err := db.Table("tz_pick_addr").Where("addr_id = ?", PickAddID).First(&pickAddr).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"code":    "A00002",
			"msg":     "PickAddr not found",
			"data":    nil,
			"success": false,
		})
		return
	}
	c.JSON(http.StatusOK, Response.ResponseBody{
		Code:      "00000",
		Data:      pickAddr,
		Msg:       "ok",
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
	})

}

// DeletePickAddrById 通过id去删除
/*
  参数：
   id: 自取地址id
 返回：
  code: 00000 成功，其他失败
  data: 是否删除成功
*/
func DeletePickAddrById(c *gin.Context) {
	var db = gorm.Db
	var ids []int64
	// 从请求参数中获取id列表
	if err := c.ShouldBindJSON(&ids); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "A00002",
			"msg":     "Invalid request",
			"data":    nil,
			"success": false,
		})
		return
	}
	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "A00005",
			"msg":     "服务器出了点小差",
			"data":    nil,
			"success": false,
		})
		return
	}
	for _, id := range ids {
		// 删除 tz_pick_addr 表中的记录
		if err := tx.Table("tz_pick_addr").Where("addr_id = ?", id).Delete(&GormModel.TzPickAddr{}).Error; err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": "A00005",
				"msg":  "服务器出了点小差",
			})
			return
		}
	}
	tx.Commit()
	c.JSON(http.StatusOK, gin.H{
		"code":    "00000",
		"msg":     "ok",
		"data":    nil,
		"success": true,
		"version": "1.0",
	})
}

// SavePickAddr 新增自取地址
/*
  参数：
   pickAddr: 自取地址信息
 返回：
  code: 00000 成功，其他失败
*/
func SavePickAddr(c *gin.Context) {
	var db = gorm.Db
	var pickAddr GormModel.TzPickAddr
	if err := c.ShouldBindJSON(&pickAddr); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "A00002",
			"msg":     "Invalid request",
			"data":    nil,
			"success": false,
		})
		return
	}
	//手动写入商铺id
	pickAddr.ShopID = 1
	log.Printf("插入的数据%+v", pickAddr)
	// 插入数据
	if err := db.Table("tz_pick_addr").Create(&pickAddr).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "A00005",
			"msg":     "服务器出了点小差",
			"data":    nil,
			"success": false,
		})
		log.Printf("插入数据失败%v", err)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":    "00000",
		"msg":     "ok",
		"data":    nil,
		"success": true,
		"version": "1.0",
	})
}

// UpdatePickAddr 更新自取地址
/*
  参数：
   pickAddr: 自取地址信息
 返回：
  code: 00000 成功，其他失败
*/
func UpdatePickAddr(c *gin.Context) {
	var db = gorm.Db
	var pickAddr GormModel.TzPickAddr

	// 绑定请求体到 pickAddr 结构体
	if err := c.ShouldBindJSON(&pickAddr); err != nil {
		log.Printf("绑定请求体到 pickAddr 结构体失败%v", err)
		c.JSON(http.StatusOK, gin.H{
			"code":    "A00002",
			"msg":     "Invalid request",
			"data":    nil,
			"success": false,
		})
		return
	}

	// 手动写入商铺id
	pickAddr.ShopID = 1

	// 开始事务
	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 检查事务是否开始成功
	if tx.Error != nil {

		c.JSON(http.StatusOK, gin.H{
			"code":    "A00005",
			"msg":     "服务器出了点小差",
			"data":    nil,
			"success": false,
		})
		return
	}

	// 更新记录
	result := tx.Table("tz_pick_addr").Where("addr_id = ?", pickAddr.AddrID).Updates(pickAddr)
	if result.Error != nil {

		tx.Rollback()
		c.JSON(http.StatusOK, gin.H{
			"code":    "A00005",
			"msg":     "服务器出了点小差",
			"data":    nil,
			"success": false,
		})
		return
	}

	// 检查是否更新成功
	if result.RowsAffected == 0 {
		tx.Rollback()
		c.JSON(http.StatusNotFound, gin.H{
			"code":    "A00005",
			"msg":     "服务器出了点小差",
			"data":    nil,
			"success": false,
		})
		return
	}

	// 提交事务
	tx.Commit()

	// 返回成功响应
	c.JSON(http.StatusOK, gin.H{
		"code":    "00000",
		"msg":     "ok",
		"data":    nil,
		"success": true,
		"version": "1.0",
	})
}
